#ifndef INPUTDATA_H
#define INPUTDATA_H

#include <map>
#include <list>
#include <string>
#include <bitset>

class InputData
{
public:
  typedef std::map<std::string, unsigned int> ButtonMap;
  typedef std::map<std::string, unsigned int> AxisMap;

  InputData();
  virtual ~InputData();

  unsigned int numButtons() const;
  unsigned int numAxes() const;

  int buttonID(const std::string& name) const; //-1 means not found
  int axisID(const std::string& name) const; //-1 means not found

  bool button(const std::string& name) const;
  bool button(unsigned int id) const;

  bool press(const std::string& name) const;
  bool press(unsigned int id) const;
  std::list<unsigned int> press() const;

  bool release(const std::string& name) const;
  bool release(unsigned int id) const;
  std::list<unsigned int> release() const;

  int axis(const std::string& name) const;
  int axis(unsigned int id) const;

  bool axisMovement(const std::string& name) const;
  bool axisMovement(unsigned int id) const;
  std::list<unsigned int> axisMovement() const;

  void setNumButtons(unsigned int number);
  void setNumAxes(unsigned int number);

  void setButton(const std::string& name, bool pressed);
  void setButton(unsigned int id, bool pressed);

  void setAxis(const std::string& name, int value);
  void setAxis(unsigned int id, int value);

  void reset();
  void ack();

  ButtonMap mButtonMap;
  AxisMap mAxisMap;

private:
  const static unsigned int MAX_BUTTONS = 128;
  const static unsigned int MAX_AXES = 8;
  const static int AXIS_MIN = -32767;
  const static int AXIS_MAX = 32767;

  std::bitset<MAX_BUTTONS> mButtons;
  std::bitset<MAX_BUTTONS> mLastButtons;
  unsigned int mNumButtons;

  int mAxes[MAX_AXES];
  int mLastAxes[MAX_AXES];
  unsigned int mNumAxes;
};

std::ostream& operator<<(std::ostream& o, const InputData& input);

#endif
